package xin.nick.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import xin.nick.common.filter.JwtAuthenticationTokenFilter;

import java.util.Arrays;

/**
 * @author Nick
 * @since 2022/7/20/020
 */
@Configuration
@Slf4j
public class WebSecurityBean {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 注入AuthenticationConfiguration
     */
    @Autowired
    private AuthenticationConfiguration authenticationConfiguration;

    /**
     * Jwt 拦截
     * @return
     */
    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter(redisTemplate);
    }

    /**
     * 配置跨域
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH",
                "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type",
                "x-auth-token"));
        configuration.setExposedHeaders(Arrays.asList("x-auth-token"));

        configuration.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);


        return source;
    }

    /**
     * 编写AuthenticationManager的bean
     */
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    /**
     * 内存认证用户信息 , 启用记得加BEAN
     * @return
     */
    public UserDetailsService userDetailsService() {

        // 密码计算
        String encodingId = "{bcrypt}";
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123456");

        log.info("初始化内存用户了");
        log.info(password);

        UserDetails user = User.builder()
                .username("user")
                .password(encodingId+password)
                .roles("USER")
                .build();
        UserDetails admin = User.builder()
                .username("admin")
                .password(encodingId+password)
                .roles("USER", "ADMIN")
                .build();
        return new InMemoryUserDetailsManager(user, admin);
    }


    /**
     * 设置密码加密类
     * @return
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * 配置呃...框架配置?
     * @return
     */
    public WebSecurityCustomizer webSecurityCustomizer() {
        // 这个配置,,, 只用来配置静态文件吧
        return web -> web.ignoring().antMatchers("/ignore1", "/ignore2");
    }


}
